package org.ww.jd.snatch;

import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.ww.jd.auction.GoodsInfo;
import org.ww.jd.auction.UnSessionUtils;
import org.ww.jd.log.Logger;

public class Snatcher {
	public static void main(String[] args) throws SQLException {
		final Snatcher s = new Snatcher();
		ScheduledExecutorService sesPrepare = Executors
				.newScheduledThreadPool(1);
		sesPrepare.scheduleAtFixedRate(new Runnable() {

			@Override
			public void run() {
				Logger.info("prepareIds start");
				try {
					int newAddIds = s.prepareIds();
					Logger.info("prepareIds end, newAddIds number = ["
							+ newAddIds + "]");
				} catch (Throwable e) {
					Logger.error(e);
					Logger.info("prepareIds end, error[" + e.getMessage() + "]");
				}
			}
		}, 0, 30, TimeUnit.MINUTES);

		ScheduledExecutorService sesExcute = Executors
				.newScheduledThreadPool(1);
		sesExcute.scheduleAtFixedRate(new Runnable() {

			@Override
			public void run() {
				Logger.info("excuteFromWaitings start");
				int excuteNumber = s.excuteFromWaitings();
				Logger.info("excuteFromWaitings end,excute number=["
						+ excuteNumber + "]");

			}
		}, 0, 10, TimeUnit.MINUTES);

	}

	private SnatchRecordDAO dao = new SnatchRecordDAO();

	public int prepareIds() {
		List<GoodsInfo> allGoods = UnSessionUtils.searchAuctionAll(true);

		List<String> ids = new ArrayList<String>();
		try {
			ids = dao.queryWaitingIds();
		} catch (SQLException e) {
			return 0;
		}
		Set<String> newIds = new HashSet<>();
		for (GoodsInfo goodsInfo : allGoods) {
			newIds.add(goodsInfo.getGoodsId());
		}
		int total = 0;
		for (String goodsid : newIds) {
			if (ids.contains(goodsid)) {
				continue;
			}
			try {
				dao.insertWaiting(goodsid);
				total++;
			} catch (SQLException e) {
				if (e.getMessage().contains("Duplicate entry")) {
					continue;
				}
				Logger.error(e);
			}
		}
		return total;
	}

	public int excuteFromWaitings() {
		int total = 0;
		List<String> ids;
		try {
			ids = dao.queryWaitingIds();
		} catch (SQLException e) {
			Logger.error(e);
			return total;
		}
		Logger.debug("waitingIds number=" + ids.size());
		for (String id : ids) {
			Logger.debug("excuteById begin: " + id);
			try {
				boolean success = excuteById(id);
				Logger.debug("excuteById end:" + id + ",success=" + success);
				if (success) {
					total++;
				}
			} catch (Throwable e) {
				Logger.error(e);
				Logger.debug("excuteById end:" + id + ",with exception="
						+ e.getMessage());
			}
		}
		return total;
	}

	private boolean excuteById(String goodsId) {

		GoodsInfo goodsInfo = UnSessionUtils.getGoods(goodsId);
		if (goodsInfo == null) {
			try {
				dao.deleteWaiting(goodsId);
				Logger.debug("delete waiting because not exist:" + goodsId);
			} catch (SQLException e) {
				Logger.error(e);
			}
			return false;

		}

		if (goodsInfo.getEndTimeMili() == null
				|| goodsInfo.getEndTimeMili() > System.currentTimeMillis()) {
			return false;
		}

		HisDealDetail detail = convert(goodsInfo);
		Double curPrice = UnSessionUtils.getCurrentPrice(goodsId);
		detail.setDealprice(curPrice);
		try {
			Logger.debug("insert begin: " + detail);
			dao.insertDetail(detail);
			Logger.debug("insert end: " + detail);
		} catch (SQLException e) {
			if (e.getMessage().contains("Duplicate entry")) {
				return false;
			}
			Logger.error(e);
			return false;
		}
		return true;

	}

	private HisDealDetail convert(GoodsInfo goodsInfo) {
		HisDealDetail detail = new HisDealDetail();
		detail.setGoodsid(goodsInfo.getGoodsId());
		detail.setGoodsname(goodsInfo.getGoodsName());
		detail.setJdprice(goodsInfo.getJDPriceDouble());
		detail.setStarttime(new Timestamp(goodsInfo.getStartTimeMili()));
		detail.setStatus(goodsInfo.getStatus());
		detail.setPlace(goodsInfo.getPlace());
		detail.setDealdatetime(new Timestamp(goodsInfo.getEndTimeMili()));
		// detail.setDealprice(goodsInfo.getCurrentPrice());

		detail.setTs(new Timestamp(System.currentTimeMillis()));
		return detail;
	}
}
